// @Date         2021-12-08
// @Author       Aaron Zhang
// @Description
// @FileName      service.go

package orm

import (
	"context"
	"errors"
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"time"
	"zin/config"
	"zin/framework/util"
)

type ProviderServiceOrm struct {
	db *gorm.DB
}

func NewProviderServiceOrm(param map[string]interface{}) (interface{}, error) {
	conf := config.Conf.Mysql
	charset := conf.Charset
	parseTime := "false"
	loc := conf.TimeLocal

	if conf.Charset == "" {
		charset = "utf8mb4"
	}

	if conf.ParseTime {
		parseTime = "True"
	}

	if conf.TimeLocal != "" {
		loc = "Local"
	}

	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=%s&loc=%s", conf.Username, conf.Password, conf.Hostname, conf.Port, conf.Db, charset, parseTime, loc)
	util.GetLogProvider().Info(context.Background(), "mysql dsn=="+dsn, nil)
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	if err != nil {
		return nil, errors.New(fmt.Sprintf("初始化数据库失败, err :%v", err))
	}

	gormConf := config.Conf.Gorm
	sqlDb, _ := db.DB()

	if gormConf.MaxOpenConn > 0 {
		sqlDb.SetMaxOpenConns(gormConf.MaxOpenConn)
	}

	if gormConf.MaxIdleConn > 0 {
		sqlDb.SetMaxIdleConns(gormConf.MaxIdleConn)
	}

	if gormConf.ConnMaxLifeTime != "" {
		maxLifeDuration, maxLifeDurationErr := time.ParseDuration(gormConf.ConnMaxLifeTime)
		if maxLifeDurationErr != nil {
			return nil, errors.New(fmt.Sprintf("解析ConnMaxLifeTime失败， err :%v", maxLifeDurationErr))
		}
		sqlDb.SetConnMaxLifetime(time.Duration(maxLifeDuration))
	}

	if err := sqlDb.Ping(); err != nil {
		return nil, errors.New(fmt.Sprintf("数据库通信失败, err :%v", err))
	}
	return &ProviderServiceOrm{db: db}, nil
}

func (p *ProviderServiceOrm) GetDb() *gorm.DB {
	return p.db
}
